package com.cloud.filter.xss;

import org.jsoup.Jsoup;
import org.jsoup.safety.Safelist;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.io.IOException;
import java.util.regex.Pattern;

public class XssFilter implements Filter {

    private static final String[] EXCLUDE_URLS = {"/login", "/register"}; // 排除的URL列表
    private static final String[] CONTENT_TYPES = {"application/x-www-form-urlencoded", "multipart/form-data", "text/xml", "application/xml", "application/json"};

    @Override
    public void init(FilterConfig filterConfig) {
        // 初始化过滤器时可以进行一些配置
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest req = (HttpServletRequest) request;
        String contentType = req.getContentType();

        // 判断是否需要过滤
        if (isExcludeUrl(req.getRequestURI())) {
            chain.doFilter(request, response);
            return;
        }

        // 包装请求对象
        chain.doFilter(new XssRequestWrapper(req), response);
    }

    @Override
    public void destroy() {
        // 销毁过滤器时可以进行一些清理工作
    }

    // 判断请求URL是否在排除列表中
    private boolean isExcludeUrl(String url) {
        for (String excludeUrl : EXCLUDE_URLS) {
            if (Pattern.matches(excludeUrl, url)) {
                return true;
            }
        }
        return false;
    }

    // 判断请求内容类型是否需要过滤
    private boolean isContentType(String contentType) {
        for (String type : CONTENT_TYPES) {
            if (contentType.startsWith(type)) {
                return true;
            }
        }
        return false;
    }

    // 请求包装类
    private static class XssRequestWrapper extends HttpServletRequestWrapper {
        public XssRequestWrapper(HttpServletRequest request) {
            super(request);
        }

        @Override
        public String getParameter(String name) {
            String value = super.getParameter(name);
            return cleanXss(value);
        }

        @Override
        public String[] getParameterValues(String name) {
            String[] values = super.getParameterValues(name);
            if (values != null) {
                for (int i = 0; i < values.length; i++) {
                    values[i] = cleanXss(values[i]);
                }
            }
            return values;
        }

        // 清理XSS攻击脚本
        private String cleanXss(String value) {
            if (value != null) {
                // 使用Jsoup清理XSS攻击脚本
                value = Jsoup.clean(value, Safelist.none());
            }
            return value;
        }
    }
}